/**
 * Creat with IntelliJ IDEA
 * Description:使用wait(),notify(),notifyAll()协调同步线程
 * wait(), notify()和notifyAll()都是Object类中的final方法，是被所有的类继承、且不允许重写的方法。
 *
 * User:WZW
 * Date:2021-11-28
 * Time:13:50
 */
class TicketSeller
{
    int fiveNumber=1, tenNumber=0, twentyNumber=0;
    public synchronized void sellTicket(int receiveMoney)
    {
        String s=Thread.currentThread().getName();
        if(receiveMoney==5)
        {
            fiveNumber = fiveNumber+1;
            System.out.println(s + " gives $5 to seller, seller gives " + s + " a ticket");
        }
        else if(receiveMoney==10){
            while(fiveNumber<1){
                try{  System.out.println(s + " gives $10 to seller");
                    System.out.println("seller asks " + s + " to wait");
                    wait();
                    System.out.println(s + " stops waiting and starts to buy...");
                }
                catch(InterruptedException e){}
            }
            fiveNumber=fiveNumber-1;
            tenNumber=tenNumber+1;
            System.out.println(s + " gives $10 to seller, seller gives " + s + " a ticket and $5");
        }
        else if(receiveMoney==20){
            while(fiveNumber<1||tenNumber<1){
                try{  System.out.println(s + " gives $20 to seller");
                    System.out.println("seller asks " + s + " to wait");
                    wait();
                    System.out.println(s+" stops waiting and starts to buy ...");
                }
                catch(InterruptedException e){}
            }
            fiveNumber = fiveNumber-1;
            tenNumber = tenNumber-1;
            twentyNumber = twentyNumber+1;
            System.out.println(s + " gives $20 to seller, seller gives " + s + " a ticket and $15");
        }
        notifyAll();
    }
}
class Cinema implements Runnable
{
    TicketSeller seller;
    String name1, name2, name3;
    Cinema(String s1,String s2,String s3)
    {
        seller = new TicketSeller();
        name1 = s1;
        name2 = s2;
        name3 = s3;
    }
    public void run()
    {
        if(Thread.currentThread().getName().equals(name1))
        {
            seller.sellTicket(20);
        }
        else if(Thread.currentThread().getName().equals(name2))
        {
            seller.sellTicket(10);
        }
        else if(Thread.currentThread().getName().equals(name3))
        {
            seller.sellTicket(5);
        }
    }
}

public class Example8_10 {
    public static void main(String args[])
    {
        String s1="Zhang", s2="Sun", s3="Zhao";
        Cinema cinema = new Cinema(s1,s2,s3);

        Thread zhang, sun, zhao;
        zhang = new Thread(cinema); // 目标对象cinema
        sun = new Thread(cinema); // 目标对象cinema
        zhao = new Thread(cinema); // 目标对象cinema
        zhang.setName(s1);
        sun.setName(s2);
        zhao.setName(s3);
        zhang.start();
        sun.start();
        zhao.start();
    }

}
